package com.debao;

import cn.hutool.core.lang.hash.Hash;
import com.alibaba.fastjson2.JSONObject;
import com.debao.common.annotation.Anonymous;
import com.debao.common.constant.WechatConstants;
import com.debao.common.core.domain.AjaxResult;
import com.debao.common.core.domain.R;
import com.debao.common.core.domain.entity.SysUser;
import com.debao.common.model.TempData;
import com.debao.common.model.WechatTemplateVo;
import com.debao.common.utils.AliyunSmsUtil;
import com.debao.common.utils.SecurityUtils;
import com.debao.common.wechat.WechatUtils;
import com.debao.dto.AppointDto;
import com.debao.system.domain.Appoint;
import com.debao.system.domain.HarvestAddress;
import com.debao.system.service.IAppointService;
import com.debao.system.service.ICourseCardService;
import com.debao.system.service.IHarvestAddressService;
import com.debao.system.service.ISysUserService;
import com.debao.wechat.ApiWechat;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 课程预约（排期）
 */
@RestController
@RequestMapping("/api/appoint")
@CrossOrigin
@Slf4j
public class ApiAppoint {

    @Resource
    private IAppointService appointService;

    @Resource
    private ICourseCardService courseCardService;

    @Resource
    private ISysUserService userService;


    private static final Integer STATUS_PASS = 1;
    private static final Integer STATUS_REJECT = -1;

    /**
     * 微信公众号API的Service
     */
    private final WxMpService wxMpService;

    private static final Logger LOGGER = LoggerFactory.getLogger(ApiWechat.class);

    public ApiAppoint(WxMpService wxMpService) {
        this.wxMpService = wxMpService;
    }


    /**
     * 获取教练的排期
     */
    @GetMapping("/coachAppointList/{coachId}/{date}")
    public AjaxResult coachAppointList(@PathVariable("coachId") Long coachId, @PathVariable("date") String date) {
        return AjaxResult.success(appointService.selectAppointList(new Appoint().setCoachId(coachId).setDate(date)));
    }


    /**
     * 获取用户指定日期的课程排期
     */
    @GetMapping("/mineAppointList/{date}")
    public AjaxResult mineAppointList(@PathVariable("date") String date) {
        Long userId = SecurityUtils.getUserId();
        return AjaxResult.success(appointService.selectAppointList(new Appoint().setUserId(userId).setDate(date)));
    }

    /**
     * 获取用户所有的课程排期
     *
     * @return
     */
    @GetMapping("/mineAppointAllList/{courseId}")
    public AjaxResult mineAppointAllList(@PathVariable("courseId") Long courseId) {
        Long userId = SecurityUtils.getUserId();
        return AjaxResult.success(appointService.selectAppointList(new Appoint().setUserId(userId).setCourseId(courseId)));
    }

    /**
     * 获取课程学员
     */
    @GetMapping("/courseUserList/{courseId}")
    public AjaxResult courseUserList(@PathVariable Long courseId) {
        return AjaxResult.success(courseCardService.courseUserList(courseId));
    }


    /**
     * 教练新增排期
     */
    @PostMapping("/addAppoint")
    public AjaxResult addAppoint(@RequestBody @Valid AppointDto dto) {
        List<Appoint> appointList = new ArrayList<>();
        dto.getDateList().forEach(date -> {
            dto.getAppointUserList().forEach(user -> {
                appointList.add(new Appoint()
                        .setCoachId(dto.getCoachId())
                        .setCourseId(dto.getCourseId())
                        .setDate(date)
                        .setStartAt(dto.getStartAt())
                        .setEndAt(dto.getEndAt())
                        .setUserId(user.getUserId())
                        .setUserName(user.getUserName()));
                //异步的方式推送微信通知
                //异步方式实现短信推送 通知给平台
                Thread threadMsg = new Thread(() -> {
                    String openId = getOpenIdByUserId(user.getUserId());
                    synchronized (this) {
                        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                                // 接收者openid
                                .toUser(openId)
                                // 模板id
                                .templateId("8KGZ0AhGTvu7qBo1groECrdCammlGix_JWXD5vjOo2I")
                                // 模板跳转链接
                                .miniProgram(new WxMpTemplateMessage.MiniProgram("wx0d1179c968aa1397", "subPackages/course/course_confirm?courseId=" + dto.getCourseId(), true))
                                .build();
                        // 添加模板数据
                        templateMessage.addData(new WxMpTemplateData("thing1", dto.getCourseName(), "#000000"))
                                .addData(new WxMpTemplateData("thing3", dto.getCoachName(), "#000000"))
                                .addData(new WxMpTemplateData("time2", dto.getStartAt() + " ~ " + dto.getEndAt(), "#000000"))
                                .addData(new WxMpTemplateData("thing4", user.getUserName(), "#000000"));
                        try {
                            // 发送模板消息
                            wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
                        } catch (WxErrorException e) {
                            log.error("·==++--·推送微信模板信息失败·--++==·", e);
                        }
                    }
                });
                threadMsg.start();

            });
        });
        appointService.batchInsertAppoint(appointList);
        return AjaxResult.success();
    }

    /**
     * pass 通过预约
     */
    @PutMapping("/pass/{id}")
    public AjaxResult pass(@PathVariable Long id) {
        int row = appointService.updateAppoint(new Appoint().setId(id).setStatus(STATUS_PASS));
        return row > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * reject 拒绝预约
     */
    @PutMapping("/reject/{id}")
    public AjaxResult reject(@PathVariable Long id) {
        int row = appointService.updateAppoint(new Appoint().setId(id).setStatus(STATUS_REJECT));
        return row > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    //批量通过预约
    @PostMapping("/batchPass")
    public AjaxResult batchPass(@RequestBody Long[] ids) {
        appointService.batchUpdateAppoint(ids, STATUS_PASS);
        return AjaxResult.success();
    }

    private String getOpenIdByUserId(Long userId) {
        String openId = userService.getAccountOpenIdByUserId(userId);
        return openId;
    }
}
